package gin2

import (
	"fmt"
	"gitee.com/chejiangyi/bsfgo/core/base2"
	"gitee.com/chejiangyi/bsfgo/core/utils"
	"gitee.com/chejiangyi/bsfgo/gin2/middleware"
	"github.com/gin-gonic/gin"
	"io"
	"os"
	"sort"
	"strings"
)

var SystemMiddlewares = []middleware.IMiddleware{&middleware.CacheBodyMiddleware{}, &middleware.CorsMiddleware{},
	&middleware.GlobalErrorMiddleware{}, &middleware.GzipMiddleware{}, &middleware.HttpPrintlnMiddleware{},
	&middleware.MaxRequestSizeMiddleware{}, &middleware.RequestIdMiddleware{}, &middleware.SessionMiddleware{},
	&middleware.SwaggerMiddleware{}, &middleware.TemplateMiddleware{}}

func InitLog() {
	if base2.BsfConfigInstance.GetLogEnabled() {
		logFile := base2.BsfConfigInstance.GetLogFile()
		if base2.BsfConfigInstance.GetLogMode() == "simple" {
			f, e := os.Create(logFile)
			if e != nil {
				panic(base2.NewBsfError2(fmt.Sprintf("日志文件创建失败:%s", logFile), e))
			}
			gin.DefaultWriter = io.MultiWriter(f, os.Stdout)
			utils.LogUtil.Info("日志文件采用simple模式,日志文件:%v", logFile)
		}
	}
}

func InitConfig() {
	utils.ConfigUtil.InitConfig("")
}

func LoadMiddleWares(r *gin.Engine, middlewares []middleware.IMiddleware, condition func(m middleware.IMiddleware) bool) string {
	var sb strings.Builder
	for _, m := range middlewares {
		if m.Enabled() && condition(m) {
			m.Middleware(r)
			sb.WriteString(fmt.Sprintf("%v(%v),", utils.ReflectUtil.GetTypeName(m), m.GetOrder()))
		}
	}
	return sb.String()
}

func InitWeb(webFunc func(*gin.Engine), middlewares ...middleware.IMiddleware) {
	//配置加载
	InitConfig()
	//日志加载
	InitLog()
	r := gin.Default()
	middlewares = append(SystemMiddlewares, middlewares...)
	//升序
	sort.Slice(middlewares, func(i, j int) bool {
		return middlewares[i].GetOrder() < middlewares[j].GetOrder()
	})
	var sb strings.Builder
	//加载<=0的
	sb.WriteString(LoadMiddleWares(r, middlewares, func(m middleware.IMiddleware) bool {
		return m.GetOrder() <= 0
	}))
	webFunc(r)
	//加载>0的
	sb.WriteString(LoadMiddleWares(r, middlewares, func(m middleware.IMiddleware) bool {
		return m.GetOrder() > 0
	}))
	utils.LogUtil.Info("中间件依次加载完成(顺序):%v", sb.String())
	utils.LogUtil.Info("服务打开端口:%v", base2.BsfConfigInstance.GetWebPort())
	err := r.Run(":" + utils.ConvertUtil.ToString(base2.BsfConfigInstance.GetWebPort()))
	if err != nil {
		utils.LogUtil.Error(err, "web严重异常退出")
	}
}
